<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>ClassLoader | YouN 科技温度</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  <meta name="keywords" content="jvm classloader" />
  
  
  
  
  <meta name="description" content="不同的 ClassLoader 之间也会有合作，它们之间的合作是通过 parent 属性和双亲委派机制来完成的。parent 具有更高的加载优先级。除此之外，parent 还表达了一种共享关系，当多个子 ClassLoader 共享同一个 parent 时，那么这个 parent 里面包含的类可以认为是所有子 ClassLoader 共享的。这也是为什么 BootstrapClassLoade">
<meta property="og:type" content="article">
<meta property="og:title" content="ClassLoader">
<meta property="og:url" content="http://this4u.cn/2020/07/06/ClassLoader/index.html">
<meta property="og:site_name" content="YouN 科技温度">
<meta property="og:description" content="不同的 ClassLoader 之间也会有合作，它们之间的合作是通过 parent 属性和双亲委派机制来完成的。parent 具有更高的加载优先级。除此之外，parent 还表达了一种共享关系，当多个子 ClassLoader 共享同一个 parent 时，那么这个 parent 里面包含的类可以认为是所有子 ClassLoader 共享的。这也是为什么 BootstrapClassLoade">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/12/1/167678affe2ff88d?imageslim">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/12/1/167678b005f268c5?imageslim">
<meta property="article:published_time" content="2020-07-06T02:49:03.000Z">
<meta property="article:modified_time" content="2023-04-13T05:58:10.683Z">
<meta property="article:author" content="Timmy">
<meta property="article:tag" content="jvm classloader">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://user-gold-cdn.xitu.io/2018/12/1/167678affe2ff88d?imageslim">
  
    <link rel="alternate" href="/atom.xml" title="YouN 科技温度" type="application/atom+xml">
  
  <link rel="icon" href="/css/images/favicon.ico">
  
    <link href="//fonts.googleapis.com/css?family=Source+Code+Pro" rel="stylesheet" type="text/css">
  
  <link href="https://fonts.googleapis.com/css?family=Open+Sans|Montserrat:700" rel="stylesheet" type="text/css">
  <link href="https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic" rel="stylesheet" type="text/css">
  <link href="//cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet">
  <style type="text/css">
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/9749f0/00000000000000000001008f/27/l?subset_id=2&fvd=n5) format("woff2");font-weight:500;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/90cf9f/000000000000000000010091/27/l?subset_id=2&fvd=n7) format("woff2");font-weight:500;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/8a5494/000000000000000000013365/27/l?subset_id=2&fvd=n4) format("woff2");font-weight:lighter;font-style:normal;}
    @font-face{font-family:futura-pt;src:url(https://use.typekit.net/af/d337d8/000000000000000000010095/27/l?subset_id=2&fvd=i4) format("woff2");font-weight:400;font-style:italic;}</style>
    
  <link rel="stylesheet" id="athemes-headings-fonts-css" href="//fonts.googleapis.com/css?family=Yanone+Kaffeesatz%3A200%2C300%2C400%2C700&amp;ver=4.6.1" type="text/css" media="all">

  <link rel="stylesheet" id="athemes-headings-fonts-css" href="//fonts.googleapis.com/css?family=Oswald%3A300%2C400%2C700&amp;ver=4.6.1" type="text/css" media="all">
  
<link rel="stylesheet" href="/css/style.css">


  
<script src="/js/jquery-3.1.1.min.js"></script>


  <!-- Bootstrap core CSS -->
  <link rel="stylesheet" href="/css/bootstrap.css" >
  <link rel="stylesheet" href="/css/fashion.css" >
  <link rel="stylesheet" href="/css/glyphs.css" >

<meta name="generator" content="Hexo 6.3.0"></head>



  <body data-spy="scroll" data-target="#toc" data-offset="50">


  


<header id="allheader" class="site-header" role="banner" 
   >
  <div class="clearfix container">
      <div class="site-branding">

          <h1 class="site-title">
            
              <a href="/" rel="home" >
                <img style="margin-bottom: 2px;"  width="126px" height="60px" alt="Hike News" src=" /css/images/youu.jpg">
              </a>
            
          </h1>
          
          
            
          <nav id="main-navigation" class="main-navigation" role="navigation">
            <a class="nav-open">Menu</a>
            <a class="nav-close">Close</a>

            <div class="clearfix sf-menu">
              <ul id="main-nav" class="menu sf-js-enabled sf-arrows"  style="touch-action: pan-y;">
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663" linktext="/"> <a class="" href="/">首页</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663" linktext="archives"> <a class="" href="/archives">归档</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663" linktext="categories"> <a class="" href="/categories">分类</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663" linktext="tags"> <a class="" href="/tags">标签</a> </li>
                    
                      <li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-1663" linktext="about"> <a class="" href="/about">关于</a> </li>
                    
              </ul>
            </div>
          </nav>

      </div>
  </div>
</header>


  <div id="container">
    <div id="wrap">
            
      <div id="content" class="outer">
        
          <section id="main" style="float:none;"><article id="post-ClassLoader" style="width: 66%; float:left;" class="article article-type-post" itemscope itemprop="blogPost" >
  <div id="articleInner" class="clearfix post-1016 post type-post status-publish format-standard has-post-thumbnail hentry category-template-2 category-uncategorized tag-codex tag-edge-case tag-featured-image tag-image tag-template">
    
    
      <header class="article-header">
        
  
    <h1 class="thumb" class="article-title" itemprop="name">
      ClassLoader
    </h1>
  

      </header>
    
    <div class="article-meta">
      
	<a href="/2020/07/06/ClassLoader/" class="article-date">
	  <time datetime="2020-07-06T02:49:03.000Z" itemprop="datePublished">七月 6, 2020</time>
	</a>

       
      
	<span id="busuanzi_container_page_pv">
	  本文总阅读量<span id="busuanzi_value_page_pv"></span>次
	</span>

    </div>
    <div class="article-entry" itemprop="articleBody">
      
        <p><img src="https://user-gold-cdn.xitu.io/2018/12/1/167678affe2ff88d?imageslim"></p>
<blockquote>
<p>不同的 ClassLoader 之间也会有合作，它们之间的合作是通过 parent 属性和双亲委派机制来完成的。parent 具有更高的加载优先级。除此之外，parent 还表达了一种共享关系，当多个子 ClassLoader 共享同一个 parent 时，那么这个 parent 里面包含的类可以认为是所有子 ClassLoader 共享的。这也是为什么 BootstrapClassLoader 被所有的类加载器视为祖先加载器，JVM 核心类库自然应该被共享。</p>
</blockquote>
<h2 id="双亲委派"><a href="#双亲委派" class="headerlink" title="双亲委派"></a>双亲委派</h2><blockquote>
<p>双亲委派规则可能会变成三亲委派，四亲委派，取决于你使用的父加载器是谁，它会一直递归委派到根加载器。</p>
</blockquote>
<h2 id="自定义加载器"><a href="#自定义加载器" class="headerlink" title="自定义加载器"></a>自定义加载器</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">ClassLoader</span> &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 加载入口，定义了双亲委派规则</span></span><br><span class="line">  Class <span class="title function_">loadClass</span><span class="params">(String name)</span> &#123;</span><br><span class="line">    <span class="comment">// 是否已经加载了</span></span><br><span class="line">    <span class="type">Class</span> <span class="variable">t</span> <span class="operator">=</span> <span class="built_in">this</span>.findFromLoaded(name);</span><br><span class="line">    <span class="keyword">if</span>(t == <span class="literal">null</span>) &#123;</span><br><span class="line">      <span class="comment">// 交给双亲</span></span><br><span class="line">      t = <span class="built_in">this</span>.parent.loadClass(name)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(t == <span class="literal">null</span>) &#123;</span><br><span class="line">      <span class="comment">// 双亲都不行，只能靠自己了</span></span><br><span class="line">      t = <span class="built_in">this</span>.findClass(name);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> t;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 交给子类自己去实现</span></span><br><span class="line">  Class <span class="title function_">findClass</span><span class="params">(String name)</span> &#123;</span><br><span class="line">    <span class="keyword">throw</span> ClassNotFoundException();</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 组装Class对象</span></span><br><span class="line">  Class <span class="title function_">defineClass</span><span class="params">(<span class="type">byte</span>[] code, String name)</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> buildClassFromCode(code, name);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">CustomClassLoader</span> <span class="keyword">extends</span> <span class="title class_">ClassLoader</span> &#123;</span><br><span class="line"></span><br><span class="line">  Class <span class="title function_">findClass</span><span class="params">(String name)</span> &#123;</span><br><span class="line">    <span class="comment">// 寻找字节码</span></span><br><span class="line">    <span class="type">byte</span>[] code = findCodeFromSomewhere(name);</span><br><span class="line">    <span class="comment">// 组装Class对象</span></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">this</span>.defineClass(code, name);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<blockquote>
<p>自定义类加载器不易破坏双亲委派规则，不要轻易覆盖 loadClass 方法。否则可能会导致自定义加载器无法加载内置的核心类库。在使用自定义加载器时，要明确好它的父加载器是谁，将父加载器通过子类的构造器传入。如果父类加载器是 null，那就表示父加载器是「根加载器」。</p>
</blockquote>
<h2 id="Class-forName-vs-ClassLoader-loadClass"><a href="#Class-forName-vs-ClassLoader-loadClass" class="headerlink" title="Class.forName vs ClassLoader.loadClass"></a>Class.forName vs ClassLoader.loadClass</h2><blockquote>
<p>这两个方法都可以用来加载目标类，它们之间有一个小小的区别，那就是 Class.forName() 方法可以获取原生类型的 Class，而 ClassLoader.loadClass() 则会报错。</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">Class&lt;?&gt; x = Class.forName(<span class="string">&quot;[I&quot;</span>);</span><br><span class="line">System.out.println(x);</span><br><span class="line"></span><br><span class="line">x = ClassLoader.getSystemClassLoader().loadClass(<span class="string">&quot;[I&quot;</span>);</span><br><span class="line">System.out.println(x);</span><br><span class="line"></span><br><span class="line">---------------------</span><br><span class="line">class [I</span><br><span class="line"></span><br><span class="line">Exception in thread <span class="string">&quot;main&quot;</span> java.lang.ClassNotFoundException: [I</span><br><span class="line">...</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="钻石依赖"><a href="#钻石依赖" class="headerlink" title="钻石依赖"></a>钻石依赖</h2><p>项目管理上有一个著名的概念叫着「钻石依赖」，是指软件依赖导致同一个软件包的两个版本需要共存而不能冲突。</p>
<p><img src="https://user-gold-cdn.xitu.io/2018/12/1/167678b005f268c5?imageslim"></p>
<p>我们平时使用的 maven 是这样解决钻石依赖的，它会从多个冲突的版本中选择一个来使用，如果不同的版本之间兼容性很糟糕，那么程序将无法正常编译运行。Maven 这种形式叫「扁平化」依赖管理。</p>
<p>使用 ClassLoader 可以解决钻石依赖问题。不同版本的软件包使用不同的 ClassLoader 来加载，<strong>位于不同 ClassLoader 中名称一样的类实际上是不同的类</strong>。下面让我们使用 URLClassLoader 来尝试一个简单的例子，它默认的父加载器是 AppClassLoader。</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">cat</span> ~/source/jcl/v1/Dep.java</span></span><br><span class="line">public class Dep &#123;</span><br><span class="line">	public void print() &#123;</span><br><span class="line">		System.out.println(&quot;v1&quot;);</span><br><span class="line">	&#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">cat</span> ~/source/jcl/v2/Dep.java</span></span><br><span class="line">public class Dep &#123;</span><br><span class="line"> public void print() &#123;</span><br><span class="line">  System.out.println(&quot;v1&quot;);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="meta prompt_"></span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">cat</span> ~/source/jcl/Test.java</span></span><br><span class="line">public class Test &#123;</span><br><span class="line">	public static void main(String[] args) throws Exception &#123;</span><br><span class="line">		String v1dir = &quot;file:///Users/qianwp/source/jcl/v1/&quot;;</span><br><span class="line">		String v2dir = &quot;file:///Users/qianwp/source/jcl/v2/&quot;;</span><br><span class="line">		URLClassLoader v1 = new URLClassLoader(new URL[]&#123;new URL(v1dir)&#125;);</span><br><span class="line">		URLClassLoader v2 = new URLClassLoader(new URL[]&#123;new URL(v2dir)&#125;);</span><br><span class="line">		</span><br><span class="line">    Class&lt;?&gt; depv1Class = v1.loadClass(&quot;Dep&quot;);</span><br><span class="line">		Object depv1 = depv1Class.getConstructor().newInstance();</span><br><span class="line">		depv1Class.getMethod(&quot;print&quot;).invoke(depv1);</span><br><span class="line"></span><br><span class="line">		Class&lt;?&gt; depv2Class = v2.loadClass(&quot;Dep&quot;);</span><br><span class="line">		Object depv2 = depv2Class.getConstructor().newInstance();</span><br><span class="line">		depv2Class.getMethod(&quot;print&quot;).invoke(depv2);</span><br><span class="line">	 </span><br><span class="line">  System.out.println(depv1Class.equals(depv2Class));</span><br><span class="line"> &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>



<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">cd</span> ~/source/jcl/v1</span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">javac Dep.java</span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">cd</span> ~/source/jcl/v2</span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">javac Dep.java</span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash"><span class="built_in">cd</span> ~/source/jcl</span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">javac Test.java</span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">java Test</span></span><br><span class="line">v1</span><br><span class="line">v2</span><br><span class="line">false</span><br></pre></td></tr></table></figure>

<p>在这个例子中如果两个 URLClassLoader 指向的路径是一样的，下面这个表达式还是 false，因为即使是同样的字节码用不同的 ClassLoader 加载出来的类都不能算同一个类</p>
<p>我们还可以让两个不同版本的 Dep 类实现同一个接口，这样可以避免使用反射的方式来调用 Dep 类里面的方法。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Class&lt;?&gt; depv1Class = v1.loadClass(<span class="string">&quot;Dep&quot;</span>);</span><br><span class="line"><span class="type">IPrint</span> <span class="variable">depv1</span> <span class="operator">=</span> (IPrint)depv1Class.getConstructor().newInstance();</span><br><span class="line">depv1.print()</span><br></pre></td></tr></table></figure>

<p>ClassLoader 固然可以解决依赖冲突问题，不过它也限制了不同软件包的操作界面必须使用反射或接口的方式进行动态调用。Maven 没有这种限制，它依赖于虚拟机的默认懒惰加载策略，运行过程中如果没有显示使用定制的 ClassLoader，那么从头到尾都是在使用 AppClassLoader，而不同版本的同名类必须使用不同的 ClassLoader 加载，所以 Maven 不能完美解决钻石依赖。 如果你想知道有没有开源的包管理工具可以解决钻石依赖的，我推荐你了解一下 sofa-ark，它是蚂蚁金服开源的轻量级类隔离框架。</p>
<h2 id="Thread-contextClassLoader"><a href="#Thread-contextClassLoader" class="headerlink" title="Thread.contextClassLoader"></a>Thread.contextClassLoader</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Thread</span> &#123;</span><br><span class="line">  ...</span><br><span class="line">  <span class="keyword">private</span> ClassLoader contextClassLoader;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> ClassLoader <span class="title function_">getContextClassLoader</span><span class="params">()</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> contextClassLoader;</span><br><span class="line">  &#125;</span><br><span class="line">  </span><br><span class="line">  <span class="keyword">public</span> <span class="keyword">void</span> <span class="title function_">setContextClassLoader</span><span class="params">(ClassLoader cl)</span> &#123;</span><br><span class="line">    <span class="built_in">this</span>.contextClassLoader = cl;</span><br><span class="line">  &#125;</span><br><span class="line">  ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>contextClassLoader「线程上下文类加载器」，这究竟是什么东西？</p>
<p>首先 contextClassLoader 是那种需要显示使用的类加载器，如果你没有显示使用它，也就永远不会在任何地方用到它。你可以使用下面这种方式来显示使用它</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Thread.currentThread().getContextClassLoader().loadClass(name);</span><br></pre></td></tr></table></figure>

<p>这意味着如果你使用 forName(string name) 方法加载目标类，它不会自动使用 contextClassLoader。那些因为代码上的依赖关系而懒惰加载的类也不会自动使用 contextClassLoader来加载。</p>
<p>其次线程的 contextClassLoader 默认是从父线程那里继承过来的，所谓父线程就是创建了当前线程的线程。程序启动时的 main 线程的 contextClassLoader 就是 AppClassLoader。这意味着如果没有人工去设置，那么所有的线程的 contextClassLoader 都是 AppClassLoader。</p>
<p>那这个 contextClassLoader 究竟是做什么用的？我们要使用前面提到了类加载器分工与合作的原理来解释它的用途。</p>
<p>它可以做到跨线程共享类，只要它们共享同一个 contextClassLoader。父子线程之间会自动传递 contextClassLoader，所以共享起来将是自动化的。</p>
<p>如果不同的线程使用不同的 contextClassLoader，那么不同的线程使用的类就可以隔离开来。</p>
<p>如果我们对业务进行划分，不同的业务使用不同的线程池，线程池内部共享同一个 contextClassLoader，线程池之间使用不同的 contextClassLoader，就可以很好的起到隔离保护的作用，避免类版本冲突。</p>
<p>如果我们不去定制 contextClassLoader，那么所有的线程将会默认使用 <strong>AppClassLoader</strong>，所有的类都将会是<strong>共享</strong>的。</p>

      
    </div>
    <footer class="entry-meta entry-footer">
      
      
  <span class="ico-tags"></span>
  <ul class="article-tag-list" itemprop="keywords"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/jvm-classloader/" rel="tag">jvm classloader</a></li></ul>

      
        
	<div id="comment">
		<!-- 来必力City版安装代码 -->
		<div id="lv-container" data-id="city" data-uid="MTAyMC8yOTQ4MS82MDQ5">
		<script type="text/javascript">
		   (function(d, s) {
		       var j, e = d.getElementsByTagName(s)[0];

		       if (typeof LivereTower === 'function') { return; }

		       j = d.createElement(s);
		       j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
		       j.async = true;

		       e.parentNode.insertBefore(j, e);
		   })(document, 'script');
		</script>
		<noscript>为正常使用来必力评论功能请激活JavaScript</noscript>
		</div>
		<!-- City版安装代码已完成 -->
	</div>



      
    </footer>
    <hr class="entry-footer-hr">
  </div>
  
    
<nav id="article-nav">
  
    <a href="/2020/08/26/jdb/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption">上一篇</strong>
      <div class="article-nav-title">
        
          jdb
        
      </div>
    </a>
  
  
    <a href="/2020/06/15/mysql-xa/" id="article-nav-older" class="article-nav-link-wrap">
      <strong class="article-nav-caption">下一篇</strong>
      <div class="article-nav-title">mysql-xa</div>
    </a>
  
</nav>

  
</article>

<!-- Table of Contents -->

  <aside id="sidebar">
    <div id="toc" class="toc-article">
    <strong class="toc-title">文章目录</strong>
    
      <ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE"><span class="nav-number">1.</span> <span class="nav-text">双亲委派</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8A%A0%E8%BD%BD%E5%99%A8"><span class="nav-number">2.</span> <span class="nav-text">自定义加载器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Class-forName-vs-ClassLoader-loadClass"><span class="nav-number">3.</span> <span class="nav-text">Class.forName vs ClassLoader.loadClass</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%92%BB%E7%9F%B3%E4%BE%9D%E8%B5%96"><span class="nav-number">4.</span> <span class="nav-text">钻石依赖</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#Thread-contextClassLoader"><span class="nav-number">5.</span> <span class="nav-text">Thread.contextClassLoader</span></a></li></ol>
    
    </div>
  </aside>
</section>
        
      </div>

    </div>
    <!-- <nav id="mobile-nav">
  
    <a href="/" class="mobile-nav-link">Home</a>
  
    <a href="/archives" class="mobile-nav-link">Archives</a>
  
    <a href="/categories" class="mobile-nav-link">Categories</a>
  
    <a href="/tags" class="mobile-nav-link">Tags</a>
  
    <a href="/about" class="mobile-nav-link">About</a>
  
</nav> -->
    <footer id="footer" class="site-footer">
  

  <div class="clearfix container">
      <div class="site-info">
		<a href="https://beian.miit.gov.cn/" target="_blank">鄂ICP备2023005434号-1</a>  	
	        Copyright &copy; 2023 YouN 科技温度 All Rights Reserved.
        
            <span id="busuanzi_container_site_uv">
              本站访客数<span id="busuanzi_value_site_uv"></span>人次  
              本站总访问量<span id="busuanzi_value_site_pv"></span>次
            </span>
          
      </div>
      <div class="site-credit">
        Theme by <a href="https://github.com/iTimeTraveler/hexo-theme-hipaper" target="_blank">hipaper</a>
      </div>
  </div>
</footer>


<!-- min height -->

<script>
    var wrapdiv = document.getElementById("wrap");
    var contentdiv = document.getElementById("content");

    wrapdiv.style.minHeight = document.body.offsetHeight - document.getElementById("allheader").offsetHeight - document.getElementById("footer").offsetHeight + "px";
    contentdiv.style.minHeight = document.body.offsetHeight - document.getElementById("allheader").offsetHeight - document.getElementById("footer").offsetHeight + "px";


    <!-- headerblur min height -->
    
    
</script>

    
<div style="display: none;">
  <script src="https://s11.cnzz.com/z_stat.php?id=1260716016&web_id=1260716016" language="JavaScript"></script>
</div>

<!-- mathjax config similar to math.stackexchange -->

<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    tex2jax: {
      inlineMath: [ ['$','$'], ["\\(","\\)"] ],
      processEscapes: true
    }
  });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Config({
      tex2jax: {
        skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
      }
    });
</script>

<script type="text/x-mathjax-config">
    MathJax.Hub.Queue(function() {
        var all = MathJax.Hub.getAllJax(), i;
        for(i=0; i < all.length; i += 1) {
            all[i].SourceElement().parentNode.className += ' has-jax';
        }
    });
</script>

<script type="text/javascript" src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>


  
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css">

  
<script src="/fancybox/jquery.fancybox.pack.js"></script>




<script src="/js/script.js"></script>


<script src="/js/bootstrap.js"></script>


<script src="/js/main.js"></script>








  <div style="display: none;">
    <script src="https://s95.cnzz.com/z_stat.php?id=1260716016&web_id=1260716016" language="JavaScript"></script>
  </div>



	<script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js">
	</script>






  </div>

  <a id="rocket" href="#top" class=""></a>
  <script type="text/javascript" src="/js/totop.js" async=""></script>
</body>
</html>
